<!DOCTYPE html>
<html>
<head>
  <link rel='stylesheet' href='qunit/qunit.css' type='text/css'/>
  <script type='text/javascript' src='../editor/lib/jquery.js'></script>
  <script type='text/javascript' src='../editor/src/browser.js'></script>
  <script type='text/javascript' src='../editor/src/svgutils.js'></script>
  <script type='text/javascript' src='../editor/src/draw.js'></script>
  <script type='text/javascript' src='qunit/qunit.js'></script>  
  <script type='text/javascript'>
  $(function() {
  	// log function
  	QUnit.log = function(result, message) {
		if (window.console && window.console.log) {
			window.console.log(result +' :: '+ message);
		}
	};

	var SVGNS = 'http://www.w3.org/2000/svg';
	var SENS = "http://svg-edit.googlecode.com";
	var XMLNSNS = "http://www.w3.org/2000/xmlns/";
	var NONCE = 'foo';
	var LAYER1 = 'Layer 1';
	var LAYER2 = 'Layer 2';
	var LAYER3 = 'Layer 3';

	var svg = document.createElementNS(SVGNS, 'svg');

	// Set up <svg> with nonce.
	var svg_n = document.createElementNS(SVGNS, 'svg');
	svg_n.setAttributeNS(XMLNSNS, 'xmlns:se', SENS);
	svg_n.setAttributeNS(SENS, 'se:nonce', NONCE); 

	var setupSvgWith3Layers = function(svgElem) {
		var layer1 = document.createElementNS(SVGNS, 'g');
		var layer1_title = document.createElementNS(SVGNS, 'title');
		layer1_title.appendChild(document.createTextNode(LAYER1));
		layer1.appendChild(layer1_title);
		svgElem.appendChild(layer1);

		var layer2 = document.createElementNS(SVGNS, 'g');
		var layer2_title = document.createElementNS(SVGNS, 'title');
		layer2_title.appendChild(document.createTextNode(LAYER2));
		layer2.appendChild(layer2_title);
		svgElem.appendChild(layer2);

		var layer3 = document.createElementNS(SVGNS, 'g');
		var layer3_title = document.createElementNS(SVGNS, 'title');
		layer3_title.appendChild(document.createTextNode(LAYER3));
		layer3.appendChild(layer3_title);
		svgElem.appendChild(layer3);
	};
	
	var cleanupSvg = function(svgElem) {
		while(svgElem.firstChild) {svgElem.removeChild(svgElem.firstChild);}
	};

	test('Test draw module', function() {
		expect(4);
		
		ok(svgedit.draw);
		equals(typeof svgedit.draw, typeof {});

		ok(svgedit.draw.Drawing);
		equals(typeof svgedit.draw.Drawing, typeof function(){});
	});
	
	test('Test document creation', function() {
		expect(3);
		
		try {
			var doc = new svgedit.draw.Drawing();
			ok(false, 'Created drawing without a valid <svg> element');
		} catch(e) {
			ok(true);
		}

		try {
			var doc = new svgedit.draw.Drawing(svg);
			ok(doc);
			equals(typeof doc, typeof {});
		} catch(e) {
			ok(false, 'Could not create document from valid <svg> element: ' + e)
		}
	});

	test('Test nonce', function() {
		expect(7);

		var doc = new svgedit.draw.Drawing(svg);
		equals(doc.getNonce(), "");

		doc = new svgedit.draw.Drawing(svg_n);
		equals(doc.getNonce(), NONCE);
		equals(doc.getSvgElem().getAttributeNS(SENS, 'nonce'), NONCE);
		
		doc.clearNonce();
		ok(!doc.getNonce());
		ok(!doc.getSvgElem().getAttributeNS(SENS, 'se:nonce'));
		
		doc.setNonce(NONCE);
		equals(doc.getNonce(), NONCE);
		equals(doc.getSvgElem().getAttributeNS(SENS, 'nonce'), NONCE);
	});
	
	test('Test getId() and getNextId() without nonce', function() {
		expect(7);
		
		var elem2 = document.createElementNS(SVGNS, 'circle');
		elem2.id = 'svg_2';
		svg.appendChild(elem2);

		var doc = new svgedit.draw.Drawing(svg);

		equals(doc.getId(), "svg_0");

		equals(doc.getNextId(), "svg_1");
		equals(doc.getId(), "svg_1");

		equals(doc.getNextId(), "svg_3");
		equals(doc.getId(), "svg_3");

		equals(doc.getNextId(), "svg_4");
		equals(doc.getId(), "svg_4");
		
		// clean out svg document
		cleanupSvg(svg);
	});

	test('Test getId() and getNextId() with prefix without nonce', function() {
		expect(7);

		var prefix = 'Bar-';
		var doc = new svgedit.draw.Drawing(svg, prefix);

		equals(doc.getId(), prefix+"0");

		equals(doc.getNextId(), prefix+"1");
		equals(doc.getId(), prefix+"1");

		equals(doc.getNextId(), prefix+"2");
		equals(doc.getId(), prefix+"2");

		equals(doc.getNextId(), prefix+"3");
		equals(doc.getId(), prefix+"3");

		cleanupSvg(svg);
	});

	test('Test getId() and getNextId() with nonce', function() {
		expect(7);
		
		var prefix = "svg_" + NONCE;

		var elem2 = document.createElementNS(SVGNS, 'circle');
		elem2.id = prefix+'_2';
		svg_n.appendChild(elem2);

		var doc = new svgedit.draw.Drawing(svg_n);

		equals(doc.getId(), prefix+"_0");

		equals(doc.getNextId(), prefix+"_1");
		equals(doc.getId(), prefix+"_1");

		equals(doc.getNextId(), prefix+"_3");
		equals(doc.getId(), prefix+"_3");

		equals(doc.getNextId(), prefix+"_4");
		equals(doc.getId(), prefix+"_4");

		cleanupSvg(svg_n);
	});

	test('Test getId() and getNextId() with prefix with nonce', function() {
		expect(7);

		var PREFIX = 'Bar-';
		var doc = new svgedit.draw.Drawing(svg_n, PREFIX);

		var prefix = PREFIX + NONCE + "_";
		equals(doc.getId(), prefix+"0");

		equals(doc.getNextId(), prefix+"1");
		equals(doc.getId(), prefix+"1");

		equals(doc.getNextId(), prefix+"2");
		equals(doc.getId(), prefix+"2");

		equals(doc.getNextId(), prefix+"3");
		equals(doc.getId(), prefix+"3");

		cleanupSvg(svg_n);
	});
	
	test('Test releaseId()', function() {
		expect(6);

		var doc = new svgedit.draw.Drawing(svg);

		var firstId = doc.getNextId();
		var secondId = doc.getNextId();

		var result = doc.releaseId(firstId);
		ok(result);
		equals(doc.getNextId(), firstId);
		equals(doc.getNextId(), "svg_3");
		
		ok(!doc.releaseId("bad-id"));
		ok(doc.releaseId(firstId));
		ok(!doc.releaseId(firstId));

		cleanupSvg(svg);
	});
	
	test('Test getNumLayers', function() {
		expect(3);
		var drawing = new svgedit.draw.Drawing(svg);
		equals(typeof drawing.getNumLayers, typeof function() {});
		equals(drawing.getNumLayers(), 0);

		setupSvgWith3Layers(svg);
		drawing.identifyLayers();
		
		equals(drawing.getNumLayers(), 3);

		cleanupSvg(svg);
	});

	test('Test hasLayer', function() {
		expect(5);

		setupSvgWith3Layers(svg);
		var drawing = new svgedit.draw.Drawing(svg);
		drawing.identifyLayers();
		
		equals(typeof drawing.hasLayer, typeof function() {});
		ok(!drawing.hasLayer('invalid-layer'));

		ok(drawing.hasLayer(LAYER3));
		ok(drawing.hasLayer(LAYER2));
		ok(drawing.hasLayer(LAYER1));

		cleanupSvg(svg);
	});
	
	test('Test identifyLayers() with empty document', function() {
		expect(9);

		var drawing = new svgedit.draw.Drawing(svg);
		
		// By default, an empty document gets an empty group created.
		drawing.identifyLayers();

		// Check that <svg> element now has one child node
		ok(drawing.getSvgElem().hasChildNodes());
		equals(drawing.getSvgElem().childNodes.length, 1);

		// Check that all_layers is correctly set up.
		equals(drawing.getNumLayers(), 1);
		var empty_layer = drawing.all_layers[0][1];
		ok(empty_layer);
		equals(empty_layer, drawing.getSvgElem().firstChild);
		equals(empty_layer.tagName, 'g');
		ok(empty_layer.hasChildNodes());
		equals(empty_layer.childNodes.length, 1);
		var firstChild = empty_layer.childNodes.item(0);
		equals(firstChild.tagName, 'title');

		cleanupSvg(svg);
	});
	
	test('Test identifyLayers() with some layers', function() {
		expect(5);
		
		var drawing = new svgedit.draw.Drawing(svg);
		setupSvgWith3Layers(svg);

		equals(svg.childNodes.length, 3);
		
		drawing.identifyLayers();
		
		equals(drawing.getNumLayers(), 3);
		equals(drawing.all_layers[0][1], svg.childNodes.item(0));
		equals(drawing.all_layers[1][1], svg.childNodes.item(1));
		equals(drawing.all_layers[2][1], svg.childNodes.item(2));

		cleanupSvg(svg);
	});

	test('Test identifyLayers() with some layers and orphans', function() {
		expect(10);
		
		setupSvgWith3Layers(svg);

		var orphan1 = document.createElementNS(SVGNS, 'rect');
		var orphan2 = document.createElementNS(SVGNS, 'rect');
		svg.appendChild(orphan1);
		svg.appendChild(orphan2);
		
		equals(svg.childNodes.length, 5);
		
		var drawing = new svgedit.draw.Drawing(svg);
		drawing.identifyLayers();
		
		equals(drawing.getNumLayers(), 4);
		equals(drawing.all_layers[0][1], svg.childNodes.item(0));
		equals(drawing.all_layers[1][1], svg.childNodes.item(1));
		equals(drawing.all_layers[2][1], svg.childNodes.item(2));
		equals(drawing.all_layers[3][1], svg.childNodes.item(3));

		var layer4 = drawing.all_layers[3][1];
		equals(layer4.tagName, 'g');
		equals(layer4.childNodes.length, 3);
		equals(layer4.childNodes.item(1), orphan1);
		equals(layer4.childNodes.item(2), orphan2);

		cleanupSvg(svg);
	});

	test('Test getLayerName()', function() {
		expect(4);
		
		var drawing = new svgedit.draw.Drawing(svg);
		setupSvgWith3Layers(svg);

		drawing.identifyLayers();
		
		equals(drawing.getNumLayers(), 3);
		equals(drawing.getLayerName(0), LAYER1);
		equals(drawing.getLayerName(1), LAYER2);
		equals(drawing.getLayerName(2), LAYER3);

		cleanupSvg(svg);
	});

	test('Test getCurrentLayer()', function() {
		expect(4);
		
		var drawing = new svgedit.draw.Drawing(svg);
		setupSvgWith3Layers(svg);
		drawing.identifyLayers();

		ok(drawing.getCurrentLayer);
		equals(typeof drawing.getCurrentLayer, typeof function(){});
		ok(drawing.getCurrentLayer());
		equals(drawing.getCurrentLayer(), drawing.all_layers[2][1]);
	});

	test('Test setCurrentLayer() and getCurrentLayerName()', function() {
		expect(6);
		
		var drawing = new svgedit.draw.Drawing(svg);
		setupSvgWith3Layers(svg);
		drawing.identifyLayers();

		ok(drawing.setCurrentLayer);
		equals(typeof drawing.setCurrentLayer, typeof function(){});
		
		drawing.setCurrentLayer(LAYER2);
		equals(drawing.getCurrentLayerName(LAYER2), LAYER2);
		equals(drawing.getCurrentLayer(), drawing.all_layers[1][1]);

		drawing.setCurrentLayer(LAYER3);
		equals(drawing.getCurrentLayerName(LAYER3), LAYER3);
		equals(drawing.getCurrentLayer(), drawing.all_layers[2][1]);

		cleanupSvg(svg);
	});
	
	test('Test createLayer()', function() {
		expect(6);
		
		var drawing = new svgedit.draw.Drawing(svg);
		setupSvgWith3Layers(svg);
		drawing.identifyLayers();
		
		ok(drawing.createLayer);
		equals(typeof drawing.createLayer, typeof function(){});
		
		var NEW_LAYER_NAME = 'Layer A';
		var layer_g = drawing.createLayer(NEW_LAYER_NAME);
		equals(4, drawing.getNumLayers());
		equals(layer_g, drawing.getCurrentLayer());
		equals(NEW_LAYER_NAME, drawing.getCurrentLayerName());
		equals(NEW_LAYER_NAME, drawing.getLayerName(3));
		
		cleanupSvg(svg);
	});
	
	test('Test getLayerVisibility()', function() {
		expect(5);
		
		var drawing = new svgedit.draw.Drawing(svg);
		setupSvgWith3Layers(svg);
		drawing.identifyLayers();
		
		ok(drawing.getLayerVisibility);
		equals(typeof drawing.getLayerVisibility, typeof function(){});
		ok(drawing.getLayerVisibility(LAYER1));
		ok(drawing.getLayerVisibility(LAYER2));
		ok(drawing.getLayerVisibility(LAYER3));
		
		cleanupSvg(svg);
	});

	test('Test setLayerVisibility()', function() {
		expect(6);
		
		var drawing = new svgedit.draw.Drawing(svg);
		setupSvgWith3Layers(svg);
		drawing.identifyLayers();
		
		ok(drawing.setLayerVisibility);
		equals(typeof drawing.setLayerVisibility, typeof function(){});

		drawing.setLayerVisibility(LAYER3, false);
		drawing.setLayerVisibility(LAYER2, true);
		drawing.setLayerVisibility(LAYER1, false);

		ok(!drawing.getLayerVisibility(LAYER1));
		ok(drawing.getLayerVisibility(LAYER2));
		ok(!drawing.getLayerVisibility(LAYER3));
		
		drawing.setLayerVisibility(LAYER3, 'test-string');
		ok(!drawing.getLayerVisibility(LAYER3));		
		
		cleanupSvg(svg);
	});

	test('Test getLayerOpacity()', function() {
		expect(5);
		
		var drawing = new svgedit.draw.Drawing(svg);
		setupSvgWith3Layers(svg);
		drawing.identifyLayers();
		
		ok(drawing.getLayerOpacity);
		equals(typeof drawing.getLayerOpacity, typeof function(){});
		ok(drawing.getLayerOpacity(LAYER1) == 1.0);
		ok(drawing.getLayerOpacity(LAYER2) == 1.0);
		ok(drawing.getLayerOpacity(LAYER3) == 1.0);
		
		cleanupSvg(svg);
	});

	test('Test setLayerOpacity()', function() {
		expect(6);
		
		var drawing = new svgedit.draw.Drawing(svg);
		setupSvgWith3Layers(svg);
		drawing.identifyLayers();
		
		ok(drawing.setLayerOpacity);
		equals(typeof drawing.setLayerOpacity, typeof function(){});

		drawing.setLayerOpacity(LAYER1, 0.4);
		drawing.setLayerOpacity(LAYER2, 'invalid-string');
		drawing.setLayerOpacity(LAYER3, -1.4);

		ok(drawing.getLayerOpacity(LAYER1) == 0.4);
		QUnit.log('layer2 opacity', drawing.getLayerOpacity(LAYER2));
		ok(drawing.getLayerOpacity(LAYER2) == 1.0);
		ok(drawing.getLayerOpacity(LAYER3) == 1.0);

		drawing.setLayerOpacity(LAYER3, 100);
		ok(drawing.getLayerOpacity(LAYER3) == 1.0);
		
		cleanupSvg(svg);
	});
	
	test('Test deleteCurrentLayer()', function() {
		expect(6);

		var drawing = new svgedit.draw.Drawing(svg);
		setupSvgWith3Layers(svg);
		drawing.identifyLayers();
		
		drawing.setCurrentLayer(LAYER2);

		var curLayer = drawing.getCurrentLayer();
		equals(curLayer, drawing.all_layers[1][1]);
		var deletedLayer = drawing.deleteCurrentLayer();
		
		equals(curLayer, deletedLayer);
		equals(2, drawing.getNumLayers());
		equals(LAYER1, drawing.all_layers[0][0]);
		equals(LAYER3, drawing.all_layers[1][0]);
		equals(drawing.getCurrentLayer(), drawing.all_layers[1][1]);
	});
	
	test('Test svgedit.draw.randomizeIds()', function() {
		expect(9);

		// Confirm in LET_DOCUMENT_DECIDE mode that the document decides
		// if there is a nonce.
		var drawing = new svgedit.draw.Drawing(svg_n.cloneNode(true));
		ok(!!drawing.getNonce());
		
		drawing = new svgedit.draw.Drawing(svg.cloneNode(true));
		ok(!drawing.getNonce());

		// Confirm that a nonce is set once we're in ALWAYS_RANDOMIZE mode.
		svgedit.draw.randomizeIds(true, drawing);
		ok(!!drawing.getNonce());

		// Confirm new drawings in ALWAYS_RANDOMIZE mode have a nonce.
		drawing = new svgedit.draw.Drawing(svg.cloneNode(true));
		ok(!!drawing.getNonce());

		drawing.clearNonce();
		ok(!drawing.getNonce());

		// Confirm new drawings in NEVER_RANDOMIZE mode do not have a nonce
		// but that their se:nonce attribute is left alone.
		svgedit.draw.randomizeIds(false, drawing);
		ok(!drawing.getNonce());
		ok(!!drawing.getSvgElem().getAttributeNS(SENS, 'nonce'));

		drawing = new svgedit.draw.Drawing(svg.cloneNode(true));
		ok(!drawing.getNonce());
		
		drawing = new svgedit.draw.Drawing(svg_n.cloneNode(true));
		ok(!drawing.getNonce());
	});

  });
  </script>
</head>  
<body>  
  <h1 id='qunit-header'>Unit Tests for draw.js</h1>
  <h2 id='qunit-banner'></h2>
  <h2 id='qunit-userAgent'></h2>
  <ol id='qunit-tests'>
  </ol>
  <div id='anchor' style='visibility:hidden'>
  </div>
</body>  
</html>
